﻿using EchoWx.Framework.Core;
using EchoWx.IService;
using EchoWx.Models;
using EchoWx.Models.DtoModel.Identity;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EchoWx.Service
{
    public class WxIdentityService : IWxIdentityService
    {
        /// <summary>
        /// 根据前台传递的code，加密数据，iv等授权登录
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<BaseResponse<AccountView>> Login(AccountLoginDto dto)
        {
            BaseResponse<AccountView> _baseResponse = new BaseResponse<AccountView>();
            //1.根据code,encryptedData,iv获取微信sessionKey，openId，unionId
            //====1.1请求微信授权API 获取session_key 和 open_Id
            var rs = await GetSessionKeyAndOpenId(dto.code);
            if (!rs.Code.Equals(ResultCode.NormalCode))
            {
                _baseResponse.Code = rs.Code;
                _baseResponse.Message = rs.Message;
                return _baseResponse;
            }
            //====1.2 根据session_key和iv 给encryptedData解密
            var rsWxData = await DecryptWxUserData(rs.Data, dto.iv, dto.encryptedData);
            if (rsWxData== null || !rsWxData.Code.Equals(ResultCode.NormalCode))
            {
                _baseResponse.Code = rs.Code;
                _baseResponse.Message = rs.Message;
                return _baseResponse;
            }
            //2.根据OpenId去本地数据库匹配是否已经存在对应的账号
            //====2.1如果存在则返回用户数据
            //====2.2用户不存在则进行其他业务操作（如果当前会员系统只服务于一个系统的，那可以直接创建用户
            //====，否则的话可以由前端进行操作绑定已有账号/注册并绑定）
            //TODO 判断用户是否存在
            if (true)
            {
                return new BaseResponse<AccountView> {
                    Data = new AccountView {
                        Account = "ceshi",
                        AvatarUrl = "http://www.******.com/****.jpg"
                    }
                };
            }
            //int IsInitAccount = int.Parse(ConfigurationManager.AppSettings["IsInitAccount"].ToString());
        }
        /// <summary>
        /// 根据Code获取SessionKey和OpenId
        /// </summary>
        /// <returns></returns>
        public async Task<BaseResponse<WxValidateUserResponse>> GetSessionKeyAndOpenId(string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                return new BaseResponse<WxValidateUserResponse> {
                    Code = ResultCode.ParametersRequired,
                    Message = "缺少以要参数Code"
                };
            }
            string urlStr = string.Format(ConfigurationManager.AppSettings["WxApiUrl"].ToString(),
                                        ConfigurationManager.AppSettings["XCXAppID"].ToString(),
                                        ConfigurationManager.AppSettings["XCXAppSecrect"].ToString(),
                                        code);
            HttpHelper _httpHelper = new HttpHelper();
            HttpItem _item = new HttpItem {
                Url = urlStr,
                Method = "GET",
                ContentType = "text/html;charset=UTF-8"
            };
            var rs = await _httpHelper.GetHtml(_item);
            if (string.IsNullOrEmpty(rs.Html))
            {
                return new BaseResponse<WxValidateUserResponse> {
                    Code = ResultCode.UnknownException,
                    Message = "请求微信授权接口出错"
                };
            }
            else
            {
                return new BaseResponse<WxValidateUserResponse>
                {
                    Data = JsonConvert.DeserializeObject<WxValidateUserResponse>(rs.Html)
                };
            }
        }

        /// <summary>
        /// 根据iv和sessionKey解密encryptedData
        /// </summary>
        /// <param name="iv"></param>
        /// <param name="sessionKey"></param>
        /// <param name="encryptedData">加密的数据</param>
        /// <returns></returns>
        public async Task<BaseResponse<WxResponseUserInfo>> DecryptWxUserData(WxValidateUserResponse vModel,string iv, string encryptedData)
        {
            GetUsersHelper.AesIV = iv;
            GetUsersHelper.AesKey = vModel.session_key;
            string result = new GetUsersHelper().AESDecrypt(encryptedData);
            var _usrInfo = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(result);
            WxResponseUserInfo responseData = new WxResponseUserInfo
            {
                nickName = _usrInfo["nickName"].ToString(),
                gender = _usrInfo["gender"].ToString(),
                city = _usrInfo["city"].ToString(),
                province = _usrInfo["province"].ToString(),
                country = _usrInfo["country"].ToString(),
                avatarUrl = _usrInfo["avatarUrl"].ToString(),
                sessionKey = vModel.session_key,
                openId = _usrInfo["openId"].ToString()
            };
            try
            {
                responseData.unionId = _usrInfo["unionId"].ToString();
            }
            catch (Exception)
            {
                responseData.unionId = "null";
            }
            return new BaseResponse<WxResponseUserInfo> {
                Data = responseData
            };
        }
    }
}
